<template>
  <!-- 数字用翻页 -->
  <div v-if="isDigit" class="flip-card">
    <div class="upper">{{ flipping ? prev : curr }}</div>
    <div class="lower">{{ flipping ? next : curr }}</div>

    <div class="flip" :class="{ go: flipping }" @animationend="onAnimEnd">
      <div class="flip-front">
        {{ prev }}
        <div v-if="flipping" class="shadow front-shadow"></div>
      </div>
      <div class="flip-back">
        {{ next }}
        <div v-if="flipping" class="shadow back-shadow"></div>
      </div>
    </div>
  </div>

  <!-- 非数字直接静态显示 -->
  <div v-else class="separator">{{ value }}</div>
</template>

<script setup>
import { ref, watch, computed } from "vue";

const props = defineProps({
  value: { type: String, required: true }
});

const isDigit = computed(() => /^\d$/.test(props.value));
const curr = ref(props.value);
const prev = ref(props.value);
const next = ref(props.value);
const flipping = ref(false);

watch(
  () => props.value,
  (newVal) => {
    if (!isDigit.value) return;
    if (newVal === curr.value || flipping.value) return;
    prev.value = curr.value;
    next.value = newVal;
    flipping.value = true;
  }
);

function onAnimEnd() {
  curr.value = next.value;
  prev.value = curr.value;
  next.value = curr.value;
  flipping.value = false;
}
</script>

<style scoped>
.flip-card {
  position: relative;
  width: 50px;
  height: 70px;
  perspective: 1000px;
}

.upper,
.lower {
  position: absolute;
  width: 100%;
  height: 50%;
  background: #333;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 40px;
  font-family: "Courier New", monospace;
  font-weight: bold;
  color: #fff;
  backface-visibility: hidden;
  border-radius: 6px;
}

.upper {
  top: 0;
  border-bottom: 2px solid #000;
}

.lower {
  bottom: 0;
  border-top: 2px solid #000;
}

.flip {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 50%;
  transform-origin: bottom;
  transform-style: preserve-3d;
}

.flip.go {
  animation: flipDown 0.6s ease-in-out forwards;
}

.flip-front,
.flip-back {
  position: absolute;
  width: 100%;
  height: 100%;
  background: #333;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 40px;
  font-family: "Courier New", monospace;
  font-weight: bold;
  color: #fff;
  backface-visibility: hidden;
  border-radius: 6px;
  overflow: hidden;
}

.flip-front {
  border-bottom: 2px solid #000;
}

.flip-back {
  transform: rotateX(180deg);
  border-top: 2px solid #000;
}

/* 阴影效果 */
.shadow {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.front-shadow {
  background: linear-gradient(to bottom, rgba(0, 0, 0, .35), rgba(0, 0, 0, 0));
  animation: frontShadowAnim 0.6s forwards;
}

.back-shadow {
  background: linear-gradient(to top, rgba(0, 0, 0, .35), rgba(0, 0, 0, 0));
  animation: backShadowAnim 0.6s forwards;
}

.separator {
  font-size: 40px;
  display: flex;
  align-items: center;
  color: #fff;
}

/* 翻页动画 */
@keyframes flipDown {
  0% {
    transform: rotateX(0deg);
  }

  100% {
    transform: rotateX(-180deg);
  }
}

/* 阴影动画 */
@keyframes frontShadowAnim {
  0% {
    opacity: 0;
  }

  35% {
    opacity: .45;
  }

  100% {
    opacity: 0;
  }
}

@keyframes backShadowAnim {
  0% {
    opacity: .45;
  }

  75% {
    opacity: .2;
  }

  100% {
    opacity: 0;
  }
}
</style>
